
import { Provide  ,Inject} from '@midwayjs/decorator';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { UserEntity } from 'src/entity/userinfo/user';
import { Repository } from 'typeorm';
import * as md5 from 'md5'
import { JwtService } from '@midwayjs/jwt';
import { Context } from '@midwayjs/koa';
// import  { Config }  from '../private/clienconfig'
import   config  from '../private/clienconfig'
import { loginDTO } from 'src/dto/login';
import { UserHistoryEntity } from 'src/entity/userinfo/userhistory';
import { RedisService } from '@midwayjs/redis';
import { PayService } from './onlypay.service';
import { AdminEntity } from 'src/entity/admin/user';
import { OrderEntity } from 'src/entity/order/orderentity';
// import  {BaseService}  from './base';
/**
 * 描述
 */
@Provide()
export class UserService  {
  @InjectEntityModel(UserEntity)
  UserinfoModel: Repository<UserEntity>;
  @InjectEntityModel(UserHistoryEntity)
  UserHistoryModel: Repository<UserHistoryEntity>;
  @InjectEntityModel(AdminEntity)
  AdminModel: Repository<AdminEntity>;
  //  导入 数据库模型  
  @InjectEntityModel(OrderEntity)
  OrderModel: Repository<OrderEntity>;



  @Inject()
  ctx: Context;

  @Inject()
  redisService: RedisService;
  @Inject()
  PayService: PayService;



/* 
 express :  req 得到所有信息
ctx 相当于 req
 
*/

  @Inject()
  jwt: JwtService;

  /**
   * 描述
   */
  async login(  userinfo:any   ) {

      //  第一步 先判断有没有 该用户名  ,如果有该用户名 但是密码不对 就是 返回密码不对
      //  如果没有该用户名, 那么就顺便创建 注重账号
      var  userdata    = await  this.UserinfoModel.find( {   where : {  username : userinfo.username } })
      //  有这个用户 , 就判断密码账号是否正确 
      console.log(userdata);
      //  没有账号  userinfo.password  userinfo 为null 没办法获取 password
      if(   userdata[0]&&  userdata[0].password == md5( userinfo.password ).toUpperCase()){
          //   登录成功
        //缓存已购的书籍
               let  book  = await this.OrderModel.createQueryBuilder('order')
                .leftJoinAndSelect("order.userId", "userId")
                .leftJoinAndSelect("order.novel", "novel")
                .where("order.orderStatus = 1")
                .andWhere("userId.id = :id", { id: userdata[0].id })
                .getMany();

                console.log("查询书籍",book);
                
             let  str =  book.map( v => v.novel.id ).join()
            console.log("用户已购数据",str);
            
                  await   this.redisService.set('userbook:'+userdata[0].id+"",str);

          //  登录成功将浏览记录导入 redis
            //  判断redis 是否存在 浏览记录
            let get1      =await   this.redisService.get('userhistory:'+userdata[0].id+"");
            if(get1 == null){
              //  查询数据库获取
              let history  =await this.UserHistoryModel.find(  {  where : {   id :userdata[0].id } })
              //  整合成对象 
              if(history !=null){
                let obj  =  history.reduce( (v,e)=> v[e.novel] =e.part  , {} )
                console.log("登录后redis缓冲文章进度",obj);
                
                  this.redisService.set('userhistory:'+userdata[0].id+"", JSON.stringify(obj) );
              }
            }



          return  { 
              code:20000,
              message:"登录成功",
              data: { 
                token:  this.jwt.signSync( {  ...userdata[0]} , config.secret ,    { expiresIn: '2d' }  ),
                expiresIn:172800,
                userinfo: userinfo
              }
          
          }
      }else if( !userdata[0]?.id){ 
        //  id为空 说明 没有该用户, 我们再注册一下
        let result :any
               result =  await  this.register(userinfo,true)      
            let {  password , ...userinfo2 } = result
            //    选择 password   ,    用userinfo2 接受剩余参数
         return  { 
              code:20000,
              message:"登录成功",
              data: { 
                token:  this.jwt.signSync( {  ...userinfo2} , config.secret ,    { expiresIn: '2d' }  ),
                expiresIn:172800,
                userinfo: userinfo2
              }
         }   
      }else{ 
        return  {  
          code:40004,
          message:"账号密码错误"
      }

      }
 
 
    }
  async adminlogin(  userinfo:any   ) {

      //  第一步 先判断有没有 该用户名  ,如果有该用户名 但是密码不对 就是 返回密码不对
      //  如果没有该用户名, 那么就顺便创建 注重账号
      var userdata    = await  this.AdminModel.findOne( {   where : {  username : userinfo.username } })
      //  有这个用户 , 就判断密码账号是否正确 
      console.log( "用户登录", userdata);
      //  没有账号  userinfo.password  userinfo 为null 没办法获取 password
      console.log(  md5( userinfo.password ).toUpperCase());
      if(userdata == null){
            return    {  
              code:40004,
              message:"账号密码错误"
          }
      }
      if(   userdata&&  userdata.password == md5( userinfo.password ).toUpperCase()){
          //   登录成功
          //  登录成功将浏览记录导入 redis
            //  判断redis 是否存在 浏览记录
         let { password , ...userinfo2  } = userdata
         
          return  { 
              code:20000,
              message:"登录成功",
              data: { 
                token:  this.jwt.signSync( {  ...userdata} , config.secret ,    { expiresIn: '2d' }  ),
                expiresIn:172800,
                userinfo: userinfo2,
                role:userdata.username  =='admin' ? ['admin'] :['agent']
              }
          
          }
      }
 
 
    }

    async checkusername(name : string){
       let result =   await  this.UserinfoModel.find( {  where : {  username : name  } })
       console.log('checkusername',result);
       
       if(result[0]){
            return { 
                code:40003,
                message :"用户名重复"
            }
       }else { 
             return { 
              code:20000,
              message :"可注册"
             }
       }
    }

    async register(userinfo : loginDTO  ,  nei  =  false ){
        let result    =  await  this.UserinfoModel.find(  {  where : {   username : userinfo.username  } } )
        if(result[0]){
          return { 
            code:40003,
            message :"用户名重复"
        }
        }else{
              userinfo.password =   userinfo.password =  md5( userinfo.password ).toUpperCase();
            let  result2 =    await this.UserinfoModel.save(userinfo)

              if(nei){
                  return    result2
              }else{
                return { 
                  code:20000,
                  message :"注册成功"
                }
              }
          
            

            
        }
   }
    async getuserhistory(){
        //  获取是哪个用户 , 直接把所有浏览记录返回给你,  但是你不要每次都来访问我这个接口
        //  后端仅仅给你 返回一次 ,不要过于依赖, 前端自己做浏览记录
        //   得到放端返回给你的数据后,  自己的项目 被别人访问了什么 自己心里有数 自己将数据 更新就好了, 没必要请求接口来重新获取
        //  除非在 Vuex  或者本地存储中把浏览记录丢失 了 再来查  
        //  每次登陆的时候 查询一次就够 


        //   1. 获取是谁   解析token 
           let user    =await  this.PayService.getuserinfo()

        //  可以直接查询 redis 中的数据,  不需要从数据库中取?  因为在用户登陆的时候已经把数据放在redis
        let get1   =await   this.redisService.get('userhistory:'+user.id);
        console.log("返回历史记录给用户" , JSON.parse(get1) );
        
        return   { 
             code:20000,
             message:"success",
             data:{ 
                history :   JSON.parse(get1)
             }

        }


   }


 






      /**
   * 获得请求IP
   */
  async getReqIP(ctx: Context) {
    const req = ctx.req;
    return (
      req.headers['x-forwarded-for'] ||
      req.socket.remoteAddress.replace('::ffff:', '')
    );

  }
}
